/*
 * Camera.cpp
 *
 *  Created on: Dec 8, 2011
 *      Author: burek
 */

#include "Camera.h"
#include "math/util.h"
#include <cmath>

#ifndef M_PI
#define M_PI (3.14159265)
#endif

Camera::Camera(float Aspect, float Near, float Far) {
	position = Vec3D::Zero;
	target = Vec3D::ZUnit;
	up = Vec3D::YUnit;

	vertFOV = 60.0f;
	aspectRatio = Aspect;

	zNear = Near;
	zFar = Far;

	camFront = Vec3D::Zero;
	camUp = Vec3D::Zero;
	camRight = Vec3D::Zero;
}

void Camera::update()
{
	float xmin, xmax, ymin, ymax;

	ymax = zNear * tan(vertFOV * 3.14159265 / 360.0);
	ymin = -ymax;

	xmin = ymin * aspectRatio;
	xmax = ymax * aspectRatio;
	projection.setPerspective(xmin, xmax, ymin, ymax, zNear, zFar);
	world.setLookAt(position, target, up, &camUp, &camRight, &camFront);
}

const Vec3D & Camera::Up() const { return camUp; }
const Vec3D & Camera::Right() const { return camRight; }
const Vec3D & Camera::Forward() const { return camFront; }

Vec3D Camera::getViewRay(float posX, float posY) const
{
	float Hnear = 2.0f * tan((vertFOV * DEG_TO_RAD) * 0.5f) * zNear;
	float Wnear = Hnear * aspectRatio;

	Vec3D d = (target - position).normalize();
	Vec3D nc = position + d * zNear;

	Vec3D res = nc + camRight * (posX * Wnear) + camUp * (posY * Hnear) - position;
	res.normalizeIP();
	return res;
}

Camera::~Camera() {}

